const WebSocket = require('ws');
const url = require('url');

let wss;
const clients = new Map();
const adminClients = new Set();

function initializeWebSocket(server) {
  wss = new WebSocket.Server({ noServer: true });

  server.on('upgrade', (request, socket, head) => {
    const pathname = url.parse(request.url).pathname;
    if (pathname === '/ws') {
      wss.handleUpgrade(request, socket, head, (ws) => {
        wss.emit('connection', ws, request);
      });
    } else {
      socket.destroy();
    }
  });

  wss.on('connection', (ws, request) => {
    const { userId, isAdmin } = getQueryParams(request.url);
  
    if (!userId) {
      console.error('No userId provided in WebSocket connection');
      ws.close(1008, 'Invalid userId');
      return;
    }

    clients.set(ws, { userId, isAdmin: isAdmin === 'true' });
  
    if (isAdmin === 'true') {
      adminClients.add(ws);
    }

    console.log(`New ${isAdmin === 'true' ? 'admin' : 'user'} connected: ${userId}`);

    ws.on('message', (message) => {
      try {
        const data = JSON.parse(message);
        if (isAdmin === 'true') {
          sendToUser(data.receiver, data);
        } else {
          sendToAdmins(data);
        }
      } catch (error) {
        console.error('Error processing message:', error);
      }
    });

    ws.on('close', () => {
      clients.delete(ws);
      if (isAdmin === 'true') {
        adminClients.delete(ws);
      }
      console.log(`Connection closed: ${userId}`);
    });
  });
}

function getQueryParams(urlString) {
  const { searchParams } = new URL(urlString, `http://${process.env.HOST || 'localhost'}`);
  return {
    userId: searchParams.get('userId'),
    isAdmin: searchParams.get('isAdmin')
  };
}

function sendToUser (userId, message) {
  console.log('sendToUser userId ==>', userId);
  clients.forEach((client, ws) => {
    if (client.userId === userId && ws.readyState === WebSocket.OPEN) {
      ws.send(JSON.stringify(message));
    }
  });
}

function sendToAdmins (message) {
  console.log('sendToAdmins message ==>', message);
  adminClients.forEach((ws) => {
    if (ws.readyState === WebSocket.OPEN) {
      ws.send(JSON.stringify(message));
    }
  });
}

module.exports = {
  initializeWebSocket,
  sendToUser,
  sendToAdmins
};